import os
import json
from MyTypeTemp import MyTypeTemp

# ---------------------------------------------

class MyTypeJSON(MyTypeTemp):
	"""MyTypeJSON gives fuse-functionality, to store data in a json-object."""

	def __init__(self, filename=None, encoding="latin1"):
		"""Constructor, initializes the temp-type-fuse-object."""

		MyTypeTemp.__init__(self)

		self.setEncoding(encoding)

		self.setTranslateBoolean(True)
		self.setTranslateNumbers(True)
		self.setTranslateNone(True)
		self.setEncoding(encoding)
		self.setIndentation(None)

		self.setFilename(filename)

		self.load()
	# End def

	def getStatStruct(self, path):
		st=MyTypeTemp.getStatStruct(self, path)

		if st:
			st.st_atime=st.st_mtime=st.ctime=os.path.getmtime(self.getFilename())
		# End if

		return st
	# End def

	def delData(self, path):
		MyTypeTemp.delData(self, path)

		self.save()
	# End def

	def setData(self, path, value):
		bufSave=value

		# Translate boolean-strings to boolean-values
		if self.getTranslateBoolean() and type(bufSave) in (str, unicode) and bufSave.strip().lower() in ("true", "false"):
			try:
				bufSave=bool(bufSave)
			except:
				pass
			# End try/except
		# End if

		# Translate number/float-strings to number/float-valuews
		if self.getTranslateNumbers() and type(bufSave) in (str, unicode):
			try:
				bufSave=long(bufSave)
			except:
				try:
					bufSave=float(bufSave)
				except:
					pass
				# End try/except
			# End try/except
		# End if

		# Tanslate None/Null-strings to none-values
		if self.getTranslateNone() and type(bufSave) in (str, unicode) and bufSave.strip().lower() in ("none", "null"):
			bufSave=None
		# End def

		# Call parent-__setitem__
		MyTypeTemp.setData(self, path, bufSave)

		# Save changes
		self.save()
	# End def

	def getSizeOf(self, path):
		# Get os-filesize of currently set filename
		size=os.path.getsize(self.getFilename())

		return size
	# End def


	def setFilename(self, filename):
		"""Set the currently used filename to store the data as a json-object."""
		if type(filename) not in (str, type(None)): raise TypeError

		self.__filename=filename
	# End def

	def getFilename(self):
		"""Returns the currently set filename."""

		return self.__filename if self.__filename not in (None, "") else None
	# End def

	def load(self):
		"""Load the json-data from the currently set filename. To avoid
		loading/saving any data from/to 'filename' can be of value 'None'."""

		if self.getFilename()!=None:
			if not os.path.exists(self.getFilename()):
				self.setData(None, {})
				self.save()
				return 0
			# End if

			js=json.load(open(self.getFilename(), "rb"), encoding=self.getEncoding())
			self.setData(None, js)
		# End if
	# End def

	def save(self):
		"""Saves the json-data to the currently set filename."""

		if self.getFilename()!=None:
			json.dump(self.getData(None), open(self.getFilename(), "wb"), indent=self.getIndentation(), encoding=self.getEncoding())
		# End if
	# End def

	def setTranslateBoolean(self, translate):
		"""Defines how boolean-strings should be transformed.

		Example:
			translate=True
			"true" => boolean, true
			"false" => boolean, false

			translate=False
			"true" => string, "true"
			"false" => string, "false"

		Parameter:
			bool translate True to translate boolean-strings to boolean-values, otherwise false.
		"""

		if type(translate)!=bool: raise TypeError
		self.__translateBoolean=translate
	# End def

	def getTranslateBoolean(self):
		"""Returns the currently set translate-boolean-setting."""

		return self.__translateBoolean
	# End def

	def setTranslateNumbers(self, translate):
		"""Defines how number-strings should be transformed.
		
		Example:
			translate=True
			"123" => integer, 123
			"123.45" => float, 123.45

			translate=False
			"123" => string, "123"
			"123.45" => string, "123.45"

		Parameter:
			bool translate True to translate number-string to number-values, otherwise false.
		"""
			
		if type(translate)!=bool: raise TypeError
		self.__translateNumbers=translate
	# End def

	def getTranslateNumbers(self):
		"""Returns the currently set translate-numbers-setting."""

		return self.__translateNumbers
	# End def

	def setTranslateNone(self, translate):
		"""Defines how none-strings should be transformed.

		Example:
			translate=True
			"none" => null, null
			"null" => null, null

			translate=False
			"none" => string, "none"
			"null" => string, "null"

		Parameter:
			bool translate True to translate none-strings to none-vallues, otherwise false.
		"""
		if type(translate)!=bool: raise TypeError
		self.__translateNone=translate
	# End def

	def getTranslateNone(self):
		"""Returns the currently set translate-none-setting."""

		return self.__translateNone
	# End def

	def setIndentation(self, indentation):
		"""Sets the indentation-level, number of spaces, the JSON-data should be saved with.

		Example:
			indentation=None or 0
			{"a": 1, "b": "b-value"}

			indendation=2
			{
			  "a": 1,
			  "b": "b-value"
			}

		Parameter:
			integer indentation Number of spaces to indent the json-file with, default no indendation.
		"""

		if indentation!=None and type(indentation)!=int: raise TypeError
		self.__indentation=indentation
	# End def

	def getIndentation(self):
		"""Returns the currently set indentation-level."""

		return self.__indentation
	# End def

# End class
